#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 二维数组的使用 与学习
int main()
{
    // 方法0、直接初始化
    int arrTmp[2][3] = {{1,2,3},{4,5,6}};
    for (int i = 0; i < 3; i++) {   // 这里应该写 < 2
        for (int j = 0; j < 3; j++) {   // 这里应该写 < 3
            printf("arrTmp = %d \n", arrTmp[i][j]);
        }
    }

    // 方法1、使用栈变量的二维数组(问题：如果二维数组较大，可能会造成栈溢出)
    printf("使用栈变量");
    // 1.1 初始化
    int arr[3][4] = {0};
    // 1.2 赋值
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            arr[i][j] = i * 10 + j;
        }
    }
    // 1.3 打印
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            printf("arr = %d \n", arr[i][j]);
        }
    }

    // 方法2、使用堆变量的二维数组, 二级指针
    printf("使用堆变量 \n");
    // 2.1 申请内存
    int **arrDyadic = NULL;
    arrDyadic = (int**)malloc(sizeof(int) * 4);    // 申请内存4行
    for(int i=0; i < 4; i++){
        arrDyadic[i] = (int*)malloc(sizeof(int) * 5); // 申请内存5 列
        memset(arrDyadic[i], 0, sizeof(arrDyadic[i]));  // 每列初始化为0
    }
    // 2.2 赋值
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 5; j++) {
            arrDyadic[i][j] = i * 10 + j;
        }
    }
    // 2.3 输出
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 5; j++) {
            printf("arrDyadic = %d \n", arrDyadic[i][j]);
        }
    }
    // 2.4 释放内存
    for(int i=0; i < 4; i++){
        free(arrDyadic[i]);
        arrDyadic[i] = NULL;
    }
    free(arrDyadic);
    arrDyadic = NULL;

    // 方法3、这样分配的内存是整块的
    int (*arrBlock)[3] = malloc(sizeof(*arrBlock) * 4); // 3行4列
    // 3.1 赋值
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 4; j++) {
            arrBlock[i][j] = i * 10 + j;
        }
    }
    // 3.2 输出
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 4; j++) {
            printf("arrBlock = %d \n", arrBlock[i][j]);
        }
    }
    // 3.3 释放内存
    free(arrBlock);
    arrBlock = NULL;
    return 0;
}

